﻿namespace TheCollectiveNetwork
{
    using System;   
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    using System.Windows.Input;  
    using System.ServiceModel.DomainServices.Client;
    using System.ServiceModel.DomainServices.Client.ApplicationServices;
    using System.Text.RegularExpressions;
    using TheCollectiveNetwork.Classes.GlobalFunctions;
    using TheCollectiveNetwork.Classes.Security;
    using TheCollectiveNetwork.Web.Services;
    using System.Windows.Media;
    
    /// <summary>
    /// <see cref="UserControl"/> class providing the main UI for the application.
    /// </summary>
    public partial class MainPage : UserControl
    {
        
        

        /*  ----------------  Initialisation Code ------------------- */
       
        /// <summary>
        /// Creates a new <see cref="MainPage"/> instance.
        /// </summary>
        public MainPage()
        {
            InitializeComponent();

            // Ensure login page is displayed on startup
            SwitchView(LoginContentControl);

            
        }
                

        /*  ----------------  Navigation Code ------------------- */
        
        /// <summary>
        /// After the Frame navigates, ensure the <see cref="HyperlinkButton"/> representing the current page is selected
        /// </summary>
        private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
        {
            // Loop through left toolbar elements
            foreach (UIElement child in ToolBarStackPanelLeftAdmin.Children)
            {
                HyperlinkButton hb = child as HyperlinkButton;
                if (hb != null && hb.NavigateUri != null)
                {
                    if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
                    {
                        VisualStateManager.GoToState(hb, "ActiveLink", true);
                    }
                    else
                    {
                        VisualStateManager.GoToState(hb, "InactiveLink", true);
                    }
                }
            }

             // Loop through right toolbar elements
            foreach (UIElement child in ToolBarStackPanelRightAdmin.Children)
            {
                HyperlinkButton hb = child as HyperlinkButton;
                if (hb != null && hb.NavigateUri != null)
                {
                    if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
                    {
                        VisualStateManager.GoToState(hb, "ActiveLink", true);
                    }
                    else
                    {
                        VisualStateManager.GoToState(hb, "InactiveLink", true);
                    }
                }
            }

           
            VisualStateManager.GoToState(ContentFrame, "Normal", false);
            VisualStateManager.GoToState(ContentFrame, "FadeIn", false);
        }

        /// <summary>
        /// If an error occurs during navigation, show an error window
        /// </summary>
        private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            e.Handled = true;
            ErrorWindow.CreateNew(e.Exception);
        }

        private void ContentFrame_Navigating(object sender, NavigatingCancelEventArgs e)
        {
            // If the user is not authenticated then do not allow navigation                 
            if (TCNauthentication.AllowAccess == false)
            {
                e.Cancel = true;               
            }
       }
             
        /*  ----------------  Click Events Code ------------------- */
        private void ToolBarLinkLogout_Click(object sender, EventArgs e)
        {
            // Log the user out
            Logout();
                        
        }


        private void LoginButton_Click(object sender, EventArgs e)
        {   
            string filteredusername;
            string filteredpassword;
            bool errorfound = false;

            // Strip out unwanted characters
            filteredusername = Regex.Replace(strfunc.Left(LoginUsernameText.Text, 255), "[^0-9a-z'\"~@_\\-\\.]", string.Empty, RegexOptions.IgnoreCase);
            filteredpassword = Regex.Replace(strfunc.Left(LoginPasswordText.Password, 255), "[^0-9a-z'\"~@_\\-\\.]", string.Empty, RegexOptions.IgnoreCase);        

            // Validate input
            if (filteredusername != LoginUsernameText.Text || filteredpassword != LoginPasswordText.Password)
            {
                // Detect unusual characters                
                LoginMessageText.Text = "Error, please only use characters or numbers.";
                LoginErrorBorder.Visibility = System.Windows.Visibility.Visible;
                errorfound = true;
            }
            else if (filteredusername.Length == 0 || filteredpassword.Length == 0) {
                // Detect zero length strings
                LoginMessageText.Text = "Error, both a username and password is required.";
                LoginErrorBorder.Visibility = System.Windows.Visibility.Visible;
                errorfound = true;
            }

            // Only proceed if username and password have been successfully validated.
            if (errorfound == false)
            {
                // Reset the error display
                LoginMessageText.Text = string.Empty;
                LoginErrorBorder.Visibility = System.Windows.Visibility.Collapsed;

                // Start the busy indicator popup
                ProcessingIndicator.DisplayApplicationBusy();

                // Do the login                
                TCNauthentication.Login(filteredusername, filteredpassword, LoginOperation_Completed);
            }

               

        }


        private void RegisterButton_Click(object sender, EventArgs e)
        {            
            DTOAccountsRegisterUser dtoaru;
            UserRegistrationContext urc;
            System.Windows.Documents.Run TextRun;
            SolidColorBrush scb_red;
            SolidColorBrush scb_green;

            //Show the busy indicator
            ProcessingIndicator.DisplayApplicationBusy();

            //Disable the button after registration to avoid multiple submissions
            RegisterButton.IsEnabled = false;
            
            // Initialise Variables                       
            RegisterMessageText.Text = string.Empty;
            scb_red = new SolidColorBrush(Colors.Red);
            scb_green = new SolidColorBrush(Colors.Green);

            // Create the context
            urc = new UserRegistrationContext();
            dtoaru = new DTOAccountsRegisterUser();
            
            dtoaru.first_name = Regex.Replace(strfunc.Left(RegisterFirstNameText.Text, 50), "[^0-9a-z'\"~@_\\-\\.]", string.Empty, RegexOptions.IgnoreCase);
            dtoaru.last_name = Regex.Replace(strfunc.Left(RegisterLastNameText.Text, 50), "[^0-9a-z'\"~@_\\-\\.]", string.Empty, RegexOptions.IgnoreCase);
            dtoaru.phone_number = Regex.Replace(strfunc.Left(RegisterPhoneText.Text, 30), "[^0-9a-z'\"~@_\\-\\.]", string.Empty, RegexOptions.IgnoreCase);
            dtoaru.organisation = Regex.Replace(strfunc.Left(RegisterOrganisationText.Text, 50), "[^0-9a-z'\"~@_\\-\\.]", string.Empty, RegexOptions.IgnoreCase);
            dtoaru.email = Regex.Replace(strfunc.Left(RegisterEmailText.Text, 255), "[^0-9a-z'\"~@_\\-\\.]", string.Empty, RegexOptions.IgnoreCase);
            dtoaru.passwordencrypt = Regex.Replace(strfunc.Left(RegisterPasswordText.Password, 255), "[^0-9a-z'\"~@_\\-\\.]", string.Empty, RegexOptions.IgnoreCase);
            
            // Insert the record
            urc.DTOAccountsRegisterUsers.Add(dtoaru);

            // Update an existing record when submit has finished
            var SubmitOp = urc.SubmitChanges();
            SubmitOp.Completed += (s, ea) =>
            {
                if (SubmitOp.HasError == false)
                {
                    //Write success message            
                    TextRun = new System.Windows.Documents.Run();
                    TextRun.Text = "Successfully registered";
                    TextRun.Foreground = scb_green;
                    RegisterMessageText.HorizontalAlignment = HorizontalAlignment.Center;
                    RegisterMessageText.Inlines.Add(TextRun);                   
                }
                else
                {
                    //Write error message            
                    TextRun = new System.Windows.Documents.Run();
                    TextRun.Text = SubmitOp.Error.Message;
                    TextRun.Foreground = scb_red;
                    RegisterMessageText.HorizontalAlignment = HorizontalAlignment.Center;
                    RegisterMessageText.Inlines.Add(TextRun);

                    //Renable the button so user can resubmit
                    RegisterButton.IsEnabled = true;

                    //Mark the error as handled
                    SubmitOp.MarkErrorAsHandled();
                }

                //Hide busy indicator
                ProcessingIndicator.HideApplicationBusy(); ;
            };   
        }

        private void RegisterCloseButton_Click(object sender, EventArgs e)
        {
            SwitchView(LoginContentControl);   
        }

        private void LoginFooterRegisterUser_Click(object sender, EventArgs e)
        {
            TextBox tb;
            PasswordBox pb;
            
            //Ensure the register button is enabled
            RegisterButton.IsEnabled = true;

            //Clear the register message
            RegisterMessageText.Text = string.Empty;

            //Clear all the text boxes, password boxes, and textblocks
            foreach (System.Windows.UIElement item in RegisterGrid.Children)
            {

                if (item is TextBox)
                {
                    tb = (TextBox)item;
                    tb.Text = String.Empty;
                }

                if (item is PasswordBox)
                {
                    pb = (PasswordBox)item;
                    pb.Password = String.Empty;
                }
                
            }
 
            //Switch the view
            SwitchView(RegisterContentControl);            
        }

        // funciton to catch the enter key on the content control and submit the form
        private void LoginContentControl_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                LoginButton_Click(sender, null); 
            }
        }

       
        /* ----------------------------------- Private Functions ---------------------------------------- */


        private void Logout()
        {

            ProcessingIndicator.DisplayApplicationBusy();

            // Do the logout
            TCNauthentication.Logout(LogoutOperation_Completed);

        }

        private void LoginOperation_Completed(LoginOperation loginOperation)
        {
            if (loginOperation.LoginSuccess)
            {
                // Load User Profile
                TCNauthentication.LoadProfile();
                
                // Blank out credentials
                LoginUsernameText.Text = string.Empty;
                LoginPasswordText.Password = string.Empty;

                // Reset the error display
                LoginMessageText.Text = string.Empty;
                LoginErrorBorder.Visibility = System.Windows.Visibility.Collapsed;

                // Load the main page after login
                SwitchView(MainContentControl);
            }
            else 
            {
                // Display login failure error
                LoginMessageText.Text = "Error, Login Failed.";                                
                LoginErrorBorder.Visibility = System.Windows.Visibility.Visible;
            }

            ProcessingIndicator.HideApplicationBusy();
        }

        private void LogoutOperation_Completed(LogoutOperation logoutOperation)
        {
            SwitchView(LoginContentControl);
            ProcessingIndicator.HideApplicationBusy();
        }


        /// <summary>
        /// Contains the logic for displaying the tool bar
        /// </summary>
        private void ChangeStateToolBar(bool display)
        {
            if (display == true)
            {
                
                if (TCNauthentication.isAdminUser)
                {
                    // Shows the tool bar for an administrator
                    ToolBarContentControlAdmin.IsEnabled = true;
                    ToolBarContentControlAdmin.Visibility = System.Windows.Visibility.Visible;

                    ToolBarContentControlUser.IsEnabled = false;
                    ToolBarContentControlUser.Visibility = System.Windows.Visibility.Collapsed;

                }
                else if (TCNauthentication.isEditAllUser || TCNauthentication.isReadAllUser || TCNauthentication.isNormalUser)
                {
                    // Shows a tool bar for a user
                    ToolBarContentControlAdmin.IsEnabled = false;
                    ToolBarContentControlAdmin.Visibility = System.Windows.Visibility.Collapsed;

                    ToolBarContentControlUser.IsEnabled = true;
                    ToolBarContentControlUser.Visibility = System.Windows.Visibility.Visible;                    
                }

            }
            else
            {
                // Disable and hide all tool bars
                ToolBarContentControlAdmin.IsEnabled = false;
                ToolBarContentControlAdmin.Visibility = System.Windows.Visibility.Collapsed;

                ToolBarContentControlUser.IsEnabled = false;
                ToolBarContentControlUser.Visibility = System.Windows.Visibility.Collapsed;      

            }
        }

       
        /// <summary>
        /// Contains the logic that coordinates what is displayed on the screen
        /// </summary>
        private void SwitchView(ContentControl conctrl)
        {
            string ControlName;

            ControlName = conctrl.Name;

            // Reset all relevant content controls on the page first
            MainContentControl.Visibility = System.Windows.Visibility.Collapsed;
            MainContentControl.IsEnabled = false;
            LoginContentControl.Visibility = System.Windows.Visibility.Collapsed;
            LoginContentControl.IsEnabled = false;
            RegisterContentControl.Visibility = System.Windows.Visibility.Collapsed;
            RegisterContentControl.IsEnabled = false;
            PasswordChangeControl.Visibility = System.Windows.Visibility.Collapsed;
            PasswordChangeControl.IsEnabled = false;
                           

            // Only allow access to the publicly accesible controls otherwise force
            // control to switch to the login page
            if (TCNauthentication.AllowAccess == false)
            {
                // Publicly accesible controls in if statement
                if (ControlName != "LoginContentControl" && ControlName != "RegisterContentControl")
                {
                    // Default if allow access is false and page not in list of publicly accessible pages
                    ControlName = "LoginContentControl";
                }

            }
            else
            {   // If access is allowed then check if a password change is required
                if (TCNauthentication.RequiresPasswordChange)
                {
                    ControlName = "PasswordChangeControl";
                }
            }
            

            switch (ControlName)
                {
                    case "MainContentControl":                                                
                        MainContentControl.Visibility = System.Windows.Visibility.Visible;
                        MainContentControl.IsEnabled = true;
                        ChangeStateToolBar(true);
                        ContentFrame.Navigate(new Uri("", UriKind.Relative));
                        break;
                    case "LoginContentControl":                        
                        LoginContentControl.Visibility = System.Windows.Visibility.Visible;
                        LoginContentControl.IsEnabled = true;
                        ChangeStateToolBar(false);                       
                        ContentFrame.Navigate(new Uri("", UriKind.Relative));                        
                        break;
                    case "RegisterContentControl":
                        RegisterContentControl.Visibility = System.Windows.Visibility.Visible;
                        RegisterContentControl.IsEnabled = true;
                        ChangeStateToolBar(false);
                        ContentFrame.Navigate(new Uri("", UriKind.Relative));
                        break;
                    case "PasswordChangeControl":
                        //PasswordChangeControlUserIDText.Text = TCNauthentication.UserID;
                        PasswordChangeControl.Visibility = System.Windows.Visibility.Visible;
                        PasswordChangeControl.IsEnabled = true;
                        MainPasswordChangeCtrl.LoadControl();
                        ChangeStateToolBar(false);
                        ContentFrame.Navigate(new Uri("", UriKind.Relative));
                        break;
                    default:
                        // Set the default to the login page
                        LoginContentControl.Visibility = System.Windows.Visibility.Visible;
                        LoginContentControl.IsEnabled = true;
                        ChangeStateToolBar(false);
                        ContentFrame.Navigate(new Uri("", UriKind.Relative));
                        break;
                }


            // Animation to fade in the control
            // ApplyTemplate is called as it seems when the page is first loaded that ApplyTemplate hasn't been
            // called on these controls by silverlight and it causes the animation to fail.
            conctrl.ApplyTemplate();
            VisualStateManager.GoToState(conctrl, "Normal", false);
            VisualStateManager.GoToState(conctrl, "FadeIn", false);
            
                
        }

        /* ----------------------------------- Custome Event Handlers ---------------------------------------- */
        private void MainPasswordChangeCtrl_CloseControl(object sender, EventArgs e)
        {
            // Log the user out
            Logout();
        }
     

    }

 }
